#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<queue>
#include<unordered_map>
#include<unistd.h>
#include<string.h>

using namespace std;

class UdpServer
{
public:
    UdpServer(uint16_t port,string ip="")
    :_port(port)
    ,_ip(ip)
    {

    }
    bool initServer()
    {
        _sock=socket(AF_INET,SOCK_DGRAM,0);
        if(_sock < 0)
        {
            cout<<"create sock failed"<<endl;
            exit(2);
        }
        struct sockaddr_in server;
        bzero(&server,sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(_port);
        server.sin_addr.s_addr=INADDR_ANY;
        if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
        {
            cout<<"bind failed"<<endl;
            exit(2);
        }
    }
    void start()
    {
        char buffer[1024];
        while(true)
        {
            struct sockaddr_in client;
            bzero(&client,sizeof(client));
            socklen_t len=sizeof(client);
            char result[256];
            char key[64];
            string cmd_echo;
            //服务器将从客户端得到的数据放入buffer
            //将信息从目标出收到sock这里来
            ssize_t s=recvfrom(_sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&client,&len);
            if(s > 0)
            {
                buffer[s]=0;
                uint16_t client_port=ntohs(client.sin_port);
                string client_ip=inet_ntoa(client.sin_addr);
                snprintf(key,sizeof(key),"%s-%u",client_ip.c_str(),client.sin_port);

                //接收到用户的信息以后还要将数据发送给用户
                auto it=_users.find(key);
                if(it==_users.end())
                {
                    _users.insert({key,client});
                }
            }
            for(auto& iter:_users)
            {
                string sendMessage=key;
                sendMessage+="#";
                sendMessage+=buffer;
                //从sock这里发过去
                sendto(_sock,sendMessage.c_str(),sendMessage.size(),0,(struct sockaddr*)&iter.second,sizeof(iter.second));
            }
        }
    }
private:
    uint16_t _port;
    string _ip;
    int _sock;
    unordered_map<string,struct sockaddr_in> _users;
    queue<string>messageQueue;
};
// class UdpServer
// {
// public:
//     UdpServer(uint16_t port,string ip="")
//     :_port(port)
//     ,_ip(ip)
//     {
       
//     }
//     bool initServer()
//     {
//         _sock=socket(AF_INET,SOCK_DGRAM,0);
//         if(_sock < 0)
//         {
//             perror("socket create");
//             exit(2);
//         }
//         struct sockaddr_in local;
//         bzero(&local,sizeof(local));
//         local.sin_family=AF_INET;
//         local.sin_port=htons(_port);
//         local.sin_addr.s_addr=INADDR_ANY;
//         if(bind(_sock,(struct sockaddr*)&local,sizeof(local)) < 0)
//         {
//             cout<<"_sock bind failed"<<endl;
//             exit(2);
//         }
//         cout<<"bind success"<<endl;
//         return true;
//     }
//     //
//     void start()
//     {
//         char buffer[1024];
//         for(;;)
//         {
//             struct sockaddr_in client;
//             bzero(&client,sizeof(client));
//             socklen_t len=sizeof(client);
//             char result[256];
//             char key[64];
//             //服务器从这里开始读取数据
//             ssize_t s = recvfrom(_sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&client,&len);
//             if(s > 0)
//             {
//                 buffer[s]=0;
//                 uint16_t client_port=ntohs(client.sin_port);
//                 string client_ip=inet_ntoa(client.sin_addr);
//                 snprintf(key,sizeof(key),"%s-%u",client_ip.c_str(),client.sin_port);
//                 auto it=_users.find(key);
//                 if(it==_users.end())
//                 {
//                     _users.insert({key,client});
//                 }
//             }
//             for(auto& iter:_users)
//             {
//                 string sendMessage=key;
//                 sendMessage+="#";
//                 sendMessage+=buffer;
//                 //我收到消息以后再将数据发送给用户
//                 sendto(_sock,sendMessage.c_str(),sendMessage.size(),0,(struct sockaddr*)&(iter.second),sizeof(iter.second));
//             }
//         }
//     }
//     ~UdpServer()
//     {
//         if(_sock >= 0)
//         {
//             //关闭sock
//             close(_sock);
//         }
//     }
// private:
//     uint16_t _port;
//     string _ip;
//     int _sock;
//     queue<string>messageQueue;
//     unordered_map<string,struct sockaddr_in>_users;
// };
